package csa_test

import (
	"git.sr.ht/~mil/mobroute/src/csa"
	"git.sr.ht/~mil/mobroute/src/db"
	"git.sr.ht/~mil/mobroute/src/logger"
	"testing"
)

type TransferPossibleBetweenConnectionsTestCaseArgs struct {
	TransfersMap            map[string]map[string]uint
	FromConnection          *db.Connection
	ToConnection            *db.Connection
	ImplicitTransferSeconds uint
	MaxTransferSeconds      uint
}

type TransferPossibleBetweenConnectionsTestCase struct {
	Test   string
	Args   TransferPossibleBetweenConnectionsTestCaseArgs
	Expect bool
}

func Test_TransferPossibleBetweenConnections(t *testing.T) {
	logger.LogWarn = true

	var (
		testCases = []TransferPossibleBetweenConnectionsTestCase{
			{
				Test: "False if the from connection's TripID == to connection's TripID",
				Args: TransferPossibleBetweenConnectionsTestCaseArgs{
					TransfersMap:            map[string]map[string]uint{},
					FromConnection:          &db.Connection{TripID: "tripfoo"},
					ToConnection:            &db.Connection{TripID: "tripfoo"},
					ImplicitTransferSeconds: 3,
					MaxTransferSeconds:      10,
				},
				Expect: false,
			},
			{
				Test: "False if SIDUs mismatch, and transfer not defined",
				Args: TransferPossibleBetweenConnectionsTestCaseArgs{
					TransfersMap:            map[string]map[string]uint{},
					FromConnection:          &db.Connection{TripID: "tripfoo", ToSSIDU: "foo", ToST: 7},
					ToConnection:            &db.Connection{TripID: "tripbar", FromSSIDU: "bar", FromST: 12},
					ImplicitTransferSeconds: 3,
					MaxTransferSeconds:      10,
				},
				Expect: false,
			},
			{
				Test: "True if SIDUs mismatch, transfer defined & lt max",
				Args: TransferPossibleBetweenConnectionsTestCaseArgs{
					TransfersMap: map[string]map[string]uint{
						"foo": map[string]uint{"bar": 2},
					},
					FromConnection:          &db.Connection{TripID: "tripfoo", ToSSIDU: "foo", ToST: 7},
					ToConnection:            &db.Connection{TripID: "tripbar", FromSSIDU: "bar", FromST: 12},
					ImplicitTransferSeconds: 3,
					MaxTransferSeconds:      10,
				},
				Expect: true,
			},
			{
				Test: "False if SIDUs mismatch, transfer defined & gt max",
				Args: TransferPossibleBetweenConnectionsTestCaseArgs{
					TransfersMap: map[string]map[string]uint{
						"foo": map[string]uint{"bar": 11},
					},
					FromConnection:          &db.Connection{TripID: "tripfoo", ToSSIDU: "foo", ToST: 2},
					ToConnection:            &db.Connection{TripID: "tripbar", FromSSIDU: "bar", FromST: 9},
					ImplicitTransferSeconds: 3,
					MaxTransferSeconds:      10,
				},
				Expect: false,
			},
			{
				Test: "True if SIDUs mismatch, transfer not defined and implicit lt max",
				Args: TransferPossibleBetweenConnectionsTestCaseArgs{
					TransfersMap:            map[string]map[string]uint{},
					FromConnection:          &db.Connection{TripID: "tripfoo", ToSSIDU: "foo", ToST: 8},
					ToConnection:            &db.Connection{TripID: "tripbar", FromSSIDU: "foo", FromST: 15},
					ImplicitTransferSeconds: 3,
					MaxTransferSeconds:      10,
				},
				Expect: true,
			},
		}
	)

	for _, testCase := range testCases {
		result := csa.TransferPossibleBetweenConnections(
			testCase.Args.TransfersMap,
			testCase.Args.FromConnection,
			testCase.Args.ToConnection,
			testCase.Args.ImplicitTransferSeconds,
			testCase.Args.MaxTransferSeconds,
		)
		if result != testCase.Expect {
			t.Fatalf("For (%v): Want %v; got %v", testCase.Test, testCase.Expect, result)
		}
	}
}
